﻿/*------------------------------------------------------------------------

MEMSTORAGE.HPP v3.4

Copyright 楊志賢 CxxlMan, 2008 - 2012
All Rights Reserved

------------------------------------------------------------------------*/
#if !defined(__MEMSTORAGE_HPP_CxxlMan)
#define __MEMSTORAGE_HPP_CxxlMan

#include "PRESERVE2.HPP"
#include "CXXLCOMPOSITE.HPP"

namespace CxxlMan
{

class MemData;
class CXXLPRESERVE_DLLEXPORT MemStorage;

CXXLPRESERVE_DLLEXPORT void cxxlFASTCALL
MemStorageExportMDC(std::ostream &out, const Smart_Ptr<MemStorage> &MemStorage_Ptr);

CXXLPRESERVE_DLLEXPORT Smart_Ptr<MemStorage> cxxlFASTCALL
MemStorageImportMDC(std::istream &MDC, ISpirit *spirit = Spirit_Easy);




// 直接儲存記憶體變數資料
class MemData:virtual public cxxlObject
{
  unsigned long m_DataLen;      // 記憶體資料陣列長度，以 byte 為單位
  const void *m_pData; // 記憶體資料陣列
public:
  MemData(unsigned long DataLen,const void *pData,ISpirit *spirit)
    :cxxlObject(spirit)
  {
    m_DataLen = DataLen;
    m_pData = new char[m_DataLen];
    for(unsigned long i = 0; i < m_DataLen; ++i)
      ((char*)m_pData)[i] = ((char*)pData)[i];
  }
  ~MemData()
  {
    delete [] (char*)m_pData;
  }


  unsigned long cxxlFASTCALL SetDataLen(unsigned long DataLen)
  {
    unsigned long tmp = m_DataLen;
    m_DataLen = DataLen;
    return tmp;
  }

  unsigned long cxxlFASTCALL GetDataLen()
  {
    return m_DataLen;
  }

  const void * cxxlFASTCALL GetData()
  {
    return m_pData;
  }

  const void * cxxlFASTCALL Get(unsigned long &DataLen)
  {
    DataLen = m_DataLen;
    return m_pData;
  }
};



/*
** 儲存體類別
*/
class CXXLPRESERVE_DLLEXPORT MemStorage:virtual public IcxxlStorage
{
  // 實際用來存放永續資料的容器
  Smart_Ptr<cxxlComposite<MemData,false> > Mem_Composite_Ptr;

  virtual bool cxxlFASTCALL toSave(cxxlPreserve *v, const UNICODE_String &Name);
  virtual bool cxxlFASTCALL toLoad(cxxlPreserve *v, const UNICODE_String &Name);

  virtual Smart_Ptr<IPreserve2Storage> cxxlFASTCALL GetIPreserve2Storage(const UNICODE_String &Name);

protected:

public:
  // Constructor
  MemStorage(ISpirit *spirit = Spirit_Easy);

  virtual ~MemStorage(){} // Destruciro

  // 成功回報 true
  // 失敗回報 false
  // 失敗原因可能是 Name 已存在或 v 為 NULL，原 Name 中的資料不會被變動。
  template<typename T> bool cxxlFASTCALL Save(const Smart_Ptr<T> &v, const UNICODE_String &Name)
  {
    T *V = v;
    return toSave(V, Name);
  }

  // 成功回報 true
  // 失敗回報 false
  // 失敗原因可能是 Name 不存在或 v 為 NULL，或是存取順序不一致，或物件(或子孫物件)已
  // 被更換過而無和永存資料對應
  template<typename T> bool cxxlFASTCALL Load(const Smart_Ptr<T> &v, const UNICODE_String &Name)
  {
    T *V = v;
    return toLoad(V, Name);
  }

  // 取得永續資料的儲存容器
  Smart_Ptr<cxxlComposite<MemData,false> > cxxlFASTCALL GetComposite()
  {
    return Mem_Composite_Ptr;
  }

  // 刪除指定名稱的永續儲存資料
  virtual bool cxxlFASTCALL Delete( const UNICODE_String &Name);

  friend CXXLPRESERVE_DLLEXPORT void cxxlFASTCALL
  MemStorageExportMDC(std::ostream &out, const Smart_Ptr<MemStorage> &MemStorage_Ptr);

  friend CXXLPRESERVE_DLLEXPORT Smart_Ptr<MemStorage> cxxlFASTCALL
  MemStorageImportMDC(std::istream &MDC, ISpirit *spirit);


};




}   /* namespace CxxlMan */
#endif
